package com.sfddata.musicpillow.gateway.filter;


import com.alibaba.fastjson.JSON;
import com.sfddata.musicpillow.common.constant.BizCodeEnum;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {

    @Autowired
    RedisTemplate redisTemplate;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        // 1.登陆服务，直接放行url
        if (request.getURI().getPath().contains("/oauth")){
            return chain.filter(exchange);
        }

        // 2.除了登陆的这些url 都要token检查
        // 没有token提示错误
        String token = request.getHeaders().getFirst("token");
        String userId = request.getHeaders().getFirst("id");
        String redisV;
        try{
            redisV = redisTemplate.opsForValue().get(userId).toString();
        }catch (Exception e){
            return unAuthorized(exchange);
        }
        // 如果这个token取不到值 或者没有token，返回unauthorized
        /**
         * expire方法
         * 从redis中获取key对应的过期时间;
         * 如果该值有过期时间，就返回相应的过期时间;
         * 如果该值没有设置过期时间，就返回-1;
         * 如果没有该值，就返回-2;
         */
        if (StringUtils.isEmpty(token) ||
                StringUtils.isEmpty(userId) ||
                !StringUtils.equals(token, redisV)) {
            return unAuthorized(exchange);
        }

        // 3.token解析失败 token超时
        // 这里没必要做token解析，业务需要的话在业务代码解析
        // 4.token通过
        return chain.filter(exchange);
    }
    @Override
    public int getOrder() {
        return -1;
    }

    public Mono<Void> unAuthorized(ServerWebExchange serverWebExchange){

        serverWebExchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
//        Result data = Result.fail(SystemErrorType.NO_POWER);
        DataBuffer buffer = serverWebExchange.getResponse().bufferFactory()
                .wrap(JSON.toJSONString(
                        new UnauthorizedResponse()
                ).getBytes(StandardCharsets.UTF_8));
        ServerHttpResponse response = serverWebExchange.getResponse();
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        //指定编码，否则在浏览器中会中文乱码
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        return response.writeWith(Mono.just(buffer));
    }
}
